package test.serialization;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

public final class StringList implements Serializable {

    private static final long serialVersionUID = -2742874800259723436L;

    private transient int size = 0;
    private transient Entry head = null;

    private static class Entry {
        String data;
        Entry next;
        Entry previous;

    }

    // Append the specified string to the list
    public final void add(String s) {

        // add first entry
        if (head == null) {
            head = new Entry();
            head.data = s;
            head.previous = null;
            head.next = null;
        } else {
            // find last entry
            Entry temp = head;
            while (temp.next != null) {
                temp = temp.next;
            }
            // add new entry to the tail
            Entry newEntry = new Entry();
            newEntry.data = s;
            newEntry.next = null;
            newEntry.previous = temp;
            temp.next = newEntry;
        }
        size++;
    }

    private void writeObject(ObjectOutputStream oos) throws IOException {
        oos.defaultWriteObject();
        oos.writeInt(size);

        for (Entry e = head; e != null; e = e.next) {
            oos.writeObject(e.data);
        }
    }

    private void readObject(ObjectInputStream ois) throws IOException,
        ClassNotFoundException {
        ois.defaultReadObject();
        int numElements = ois.readInt();

        for (int i = 0; i < numElements; i++) {
            add((String) ois.readObject());
        }
    }

    public void display() {
        System.out.println(this.size);
        for (Entry temp = head; temp != null; temp = temp.next) {
            System.out.print(temp.data + "\t");
        }
        System.out.println();
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        StringList list = new StringList();
        for (int i = 0; i < 10; i++) {
            list.add("index" + i);
        }
        try {

            // Serialization
            File file = new File("stringListSerial");
            FileOutputStream fos = new FileOutputStream(file);
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            oos.writeObject(list);
            oos.close();
            fos.close();

            // Deserialization
            FileInputStream fis = new FileInputStream(file);
            ObjectInputStream ois = new ObjectInputStream(fis);
            StringList deserialList = (StringList) ois.readObject();
            ois.close();
            fis.close();

            // Validation
            list.display();
            deserialList.display();
            if (list.equals(deserialList))
                System.out.println("equal!");
            else
                System.out.println("not equal!");
            System.out.println(list.hashCode());
            System.out.println(deserialList.hashCode());

        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }
}
